package com.ruoyi.health.report.action.processor;

import com.ruoyi.health.report.action.SaveImageAction;
import com.ruoyi.health.report.utils.ZkxcImageUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.util.*;

/**
 * SaveImageAction注解处理器
 * 用于在获取到实体值之后调用ZkxcImageUtil中的方法处理图片
 *
 * @author ChenYF
 * @date 2025-09-08 14:40
 */
@Component
public class SaveImageActionProcessor {

    @Autowired
    private ZkxcImageUtil zkxcImageUtil;

    /**
     * 处理对象中带有SaveImageAction注解的字段
     *
     * @param obj        包含注解的对象
     * @param customerId 客户ID
     * @param recordId   记录ID
     */
    public void processSaveImageAction(Object obj, Long customerId, Long recordId) {
        if (obj == null) {
            return;
        }

        Set<Object> processedObjects = new HashSet<>();
        processFields(obj, customerId, recordId, processedObjects);
    }

    /**
     * 递归处理对象及其嵌套对象中的@SaveImageAction注解
     *
     * @param obj              当前处理的对象
     * @param customerId       客户ID
     * @param recordId         记录ID
     * @param processedObjects 已处理的对象集合，防止循环引用
     */
    private void processFields(Object obj, Long customerId, Long recordId, Set<Object> processedObjects) {
        if (obj == null || processedObjects.contains(obj)) {
            return;
        }

        // 将当前对象添加到已处理集合中
        processedObjects.add(obj);

        Class<?> clazz = obj.getClass();
        Field[] fields = clazz.getDeclaredFields();

        for (Field field : fields) {
            try {
                field.setAccessible(true);

                // 处理带有@SaveImageAction注解的字段
                if (field.isAnnotationPresent(SaveImageAction.class)) {
                    Object value = field.get(obj);
                    SaveImageAction annotation = field.getAnnotation(SaveImageAction.class);

                    // 获取字段名称作为imageKey的默认值
                    String imageKey = annotation.imageKey().getKey();
                    if (imageKey == null || imageKey.isEmpty()) {
                        imageKey = field.getName();
                    }

                    if (value instanceof String && !((String) value).isEmpty()) {
                        // 调用ZkxcImageUtil中的方法处理图片
                        System.out.println("当前正在处理图片："+ imageKey);
                        String url = zkxcImageUtil.getImageUrl(customerId, recordId, imageKey, (String) value);
                        // 将获取到的字段值赋值回原字段
                        field.set(obj, url);
                    }
                } else {
                    // 递归处理嵌套对象
                    Object fieldValue = field.get(obj);
                    if (fieldValue != null) {
                        if (fieldValue.getClass().isArray()) {
                            // 处理数组
                            if (!isPrimitiveOrWrapper(fieldValue.getClass().getComponentType())) {
                                Object[] array = (Object[]) fieldValue;
                                for (Object element : array) {
                                    processFields(element, customerId, recordId, processedObjects);
                                }
                            }
                        } else if (fieldValue instanceof Collection) {
                            // 处理集合
                            Collection<?> collection = (Collection<?>) fieldValue;
                            for (Object element : collection) {
                                if (element != null && !isPrimitiveOrWrapper(element.getClass())) {
                                    processFields(element, customerId, recordId, processedObjects);
                                }
                            }
                        } else if (!isPrimitiveOrWrapper(fieldValue.getClass())) {
                            // 处理普通对象
                            processFields(fieldValue, customerId, recordId, processedObjects);
                        }
                    }
                }
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 判断是否为基本类型或其包装类
     *
     * @param clazz 类
     * @return 是否为基本类型或其包装类
     */
    private boolean isPrimitiveOrWrapper(Class<?> clazz) {
        return clazz.isPrimitive()
                || clazz == String.class
                || clazz == Boolean.class
                || clazz == Character.class
                || clazz == Byte.class
                || clazz == Short.class
                || clazz == Integer.class
                || clazz == Long.class
                || clazz == Float.class
                || clazz == Double.class;
    }
}
